package com.bjpowernode.shop.controller;

import com.alibaba.fastjson.JSON;
import com.bjpowernode.shop.base.BaseMember;
import com.bjpowernode.shop.constants.CommonConstants;
import com.bjpowernode.shop.constants.QueueConstants;
import com.bjpowernode.shop.domain.SmsMessage;
import com.bjpowernode.shop.domain.User;
import com.bjpowernode.shop.domain.WxMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/p/sms")
public class MessageController extends BaseMember implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void initCallBack() {
        // 注册发送者的消息确认模式的回调方法
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    // 生成短信验证码，发送到消息队列中
    @PostMapping("/send")
    public ResponseEntity<String> sms2Queue(@RequestBody SmsMessage smsMessage) {
        // 生成短信验证码
        int randomCode = RandomUtils.nextInt(1000, 9999);
        System.out.println("randomCode = " + randomCode);

        // 将验证码存入到redis中
        String phonenum = smsMessage.getPhonenum();
        redisTemplate.opsForValue().set(CommonConstants.BINDING_PHONE_NUM_PREFIX + phonenum,
                String.valueOf(randomCode), 5, TimeUnit.MINUTES);

        String stringUserId = getStringUserId();
        System.out.println("stringUserId = " + stringUserId);

        // 将短信实体类发送到消息队列中
        rabbitTemplate.convertAndSend(
                // 交换机名称，不指定则为默认交换机，
                // 直接写消息队列的名称
                QueueConstants.PHONE_SMS_QUEUE,
                // json
                JSON.toJSONString(
                        smsMessage.setCode(randomCode).setUserId(getStringUserId())
                )
        );

        return ResponseEntity.ok("消息发送成功");
    }

    @PostMapping("/savePhone")
    @Transactional
    public ResponseEntity<String> savePhone(@RequestBody SmsMessage smsMessage) {
        // 校验短信验证码合法性
        String realCode = redisTemplate.opsForValue().get(CommonConstants.BINDING_PHONE_NUM_PREFIX + smsMessage.getPhonenum());
        if (!realCode.equals(String.valueOf(smsMessage.getCode()))) {
            return ResponseEntity.ok("验证码有误,请重新输入");
        }
        
        // 修改用户表数据
        User user = userService.getById(getStringUserId());
        user.setUserMobile(smsMessage.getPhonenum()).setModifyTime(new Date());
        userService.updateById(user);
        return ResponseEntity.ok("手机号修改成功");
    }
    
    @GetMapping("sendWx/{openId}")
    public ResponseEntity<String> sendWxMsg(@PathVariable String openId){
        // 封装要发送的消息
        WxMsg wxMsg = WxMsg.builder()
                .userId(getStringUserId())
                .touser(openId)
                .topcolor("#00FF00")
                .template_id("FRI30KqoSBqMy3bzrcY3yCnbLSPbjJQABWQ-EXxOOUc")
                .url("https://www.baidu.com")
                .build();
        String time = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
        wxMsg.append("time",time,"#173177");
        wxMsg.append("prod","漫画书","#173177");
        wxMsg.append("money","88.00","#173177");
        wxMsg.append("balance","9999.00","#173177");
        
        rabbitTemplate.convertAndSend(
                QueueConstants.WX_MSG_QUEUE,
                JSON.toJSONString(wxMsg)
        );
        
        return ResponseEntity.ok("消息发送成功");
    }

    @Override
    // 消息是否路由到指定交换机中
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info("CorrelationData : {}, ack : {}, cause: {}", correlationData, ack, cause);

        if (!ack)
            throw new RuntimeException("消息发送失败");
    }

    @Override
    // 消息是否转发到指定消息队列中
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {

    }
}
